﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Code.Models
{
    /// <summary>
    /// 用于描述对象之间的比较方式
    /// </summary>
    public struct Comparison
    {
        private string _Operato;
        public bool IsRange { get; private set; }

        #region 公共枚举
        /// <summary>
        /// "=" 等于
        /// </summary>
        public static Comparison Equal
        { 
            get { return new Comparison() { _Operato = "=" }; } 
        }
        /// <summary>
        /// "&lt;&gt;" 不等于
        /// </summary>
        public static Comparison UnEqual
        {
            get { return new Comparison() { _Operato = "<>" }; }
        }
        /// <summary>
        /// "&gt;" 大于
        /// </summary>
        public static Comparison GreaterThan
        {
            get { return new Comparison() { _Operato = ">" }; }
        }
        /// <summary>
        /// "&gt;=" 大于等于
        /// </summary>
        public static Comparison GreaterThanOrEqual
        {
            get { return new Comparison() { _Operato = ">=" }; }
        }
        /// <summary>
        /// "&lt;" 小于
        /// </summary>
        public static Comparison LessThan
        {
            get { return new Comparison() { _Operato = "<" }; }
        }
        /// <summary>
        /// "&lt;=" 小于等于
        /// </summary>
        public static Comparison LessThanOrEqual
        {
            get { return new Comparison() { _Operato = "<=" }; }
        }
        /// <summary>
        /// 对两个对象表达式执行逻辑比较
        /// </summary>
        public static Comparison Is
        {
            get { return new Comparison() { _Operato = "IS"}; }
        }
        /// <summary>
        /// 对两个对象表达式执行逻辑比较并反
        /// </summary>
        public static Comparison IsNot
        {
            get { return new Comparison() { _Operato = "IS NOT"}; }
        }
        /// <summary>
        /// 确定给定的值是否存在于子查询或列表中
        /// </summary>
        public static Comparison In
        {
            get { return new Comparison() { _Operato = "IN", IsRange = true }; }
        }
        /// <summary>
        /// 确定给定的值是否不子查询或列表中
        /// </summary>
        public static Comparison NotIn
        {
            get { return new Comparison() { _Operato = "NotIN", IsRange = true }; }
        }
        /// <summary>
        /// 确定给定的值是否属于一个范围
        /// </summary>
        public static Comparison Between
        {
            get { return new Comparison() { _Operato = "BETWEEN", IsRange = true }; }
        }
        /// <summary>
        /// 确定给定的值是否不属于一个范围
        /// </summary>
        public static Comparison NotBetween
        {
            get { return new Comparison() { _Operato = "NOT BETWEEN", IsRange = true }; }
        }

        /// <summary>
        /// 用于使用SQL语句来确定条件
        /// </summary>
        public static Comparison Sql
        {
            get { return new Comparison { _Operato = "Sql" }; }
        }
        /// <summary>
        /// 用于伪造一个True条件
        /// </summary>
        public static Comparison True { get { return new Comparison { _Operato = "1 = 1" }; } }
        #endregion

        #region 重写 object 的方法
        public override bool Equals(object obj)
        {
            if(obj==null||!(obj is Comparison))
                throw new System.ArgumentOutOfRangeException("当前 Comparison 不可用");
            if(string.IsNullOrEmpty(this._Operato)||string.IsNullOrEmpty(((Comparison)obj)._Operato))
                throw new System.ArgumentOutOfRangeException("当前 Comparison 不可用");

            bool rs = false;
            if (obj is Comparison)
            {
                rs = this._Operato.Equals(((Comparison)obj)._Operato);
            }
            return rs;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            if(string.IsNullOrEmpty(this._Operato))
                throw new System.ArgumentOutOfRangeException("当前 Comparison 不可用");
           
            return _Operato.ToString();
        }

        public static bool operator ==(Comparison compar1,Comparison compar2)
        {
            return compar1.Equals(compar2);
        }
        public static bool operator !=(Comparison compar1, Comparison compar2)
        {
            return !compar1.Equals(compar2);
        }
        #endregion
    }

    /// <summary>
    /// 表示要使用指定的比较方式
    /// </summary>
    public class ComparValue
    {
        /// <summary>
        /// 表示要使用指定的比较方式
        /// </summary>
        public ComparValue() { }
        /// <summary>
        /// 表示要使用指定的比较方式
        /// </summary>
        /// <param name="compar">比较方式</param>
        /// <param name="val">要比较的值</param>
        public ComparValue(Comparison compar, object val)
        {
            this.Compar = compar;
            this.Value = val;
        }
        /// <summary>
        /// 需要用到范围性的比较
        /// </summary>
        /// <param name="compar">比较方式</param>
        /// <param name="val">范围的起始值</param>
        /// <param name="valEnd">范围的终止值</param>
        /// <exception cref="System.ArgumentOutOfRangeException" />
        public ComparValue(Comparison compar, object val, object valEnd)
        {
            if (compar.Equals(Comparison.Between) || compar.Equals(Comparison.NotBetween))
            {
                this.Compar = compar;
                this.Value = val;
                this.ValueEnd = valEnd;
            }
            else
            {
                throw new System.ArgumentOutOfRangeException("比较方式只能是 ComparisonOperator.Between 或 ComparisonOperator.NotBetween");
            }
        }

        /// <summary>
        /// 比较方式
        /// </summary>
        public Comparison Compar { get; set; }
        /// <summary>
        /// 比较值
        /// </summary>
        public object Value { get; set; }
        /// <summary>
        /// 当比较为一个范围时使用
        /// </summary>
        public object ValueEnd { get; set; }
    }

    /// <summary>
    /// 表示Sql表达式
    /// </summary>
    public class SqlExpression
    {
        public string Expression { get; set; }
        public object[] Params { get; set; }

        public SqlExpression(string expression, params object[] args)
        {
            this.Expression = expression;
            this.Params = args;
        }
    }

    public struct Opterator
    {
        private Func<string,string,string> _func;

        private string _opterator;

        #region 公共枚举

        /// <summary>
        /// "+=" 加等于 
        /// </summary>
        public static Opterator Add
        {
            get 
            {
                return new Opterator()
                {
                    _opterator="+",
                    _func = (name,param) => string.Format("[{0}] = [{0}] + {1}",name,param)
                };
            }
        }

        /// <summary>
        /// "-=" 减等于
        /// </summary>
        public static Opterator Subtract
        {
            get
            {
                return new Opterator()
                {
                    _opterator = "-",
                    _func = (name,param) => string.Format("[{0}] = [{0}] - {1}",name,param)
                };
            }
        }

        /// <summary>
        /// "*=" 乘等于
        /// </summary>
        public static Opterator Multiply
        {
            get
            {
                return new Opterator()
                {
                    _opterator = "*",
                    _func = (name, param) => string.Format("[{0}] = [{0}] * {1}", name, param)
                };
            }
        }

        /// <summary>
        /// "/=" 除等于
        /// </summary>
        public static Opterator Divide
        {
            get
            {
                return new Opterator()
                {
                    _opterator = "/",
                    _func = (name, param) => string.Format("[{0}] = [{0}] / {1}", name, param)
                };
            }
        }
        public static Opterator Replace
        {
            get
            {
                return new Opterator()
                {
                    _func = (name, param) => string.Format("[{0}] = [{0}] / {1}", name, param)
                };
            }
        }
        #endregion

        /// <summary>
        /// 生成语句 " [列名] = [列名] + 参数名"
        /// </summary>
        /// <param name="name">列名</param>
        /// <param name="param">参数名</param>
        public string ToOpteratorString(string name, string param)
        {
            return _func(name, param);
        }

        #region 重写 object 的方法

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
            if (obj is Opterator)
            {
                Opterator tmp = (Opterator)obj;

                return _opterator.Equals(tmp._opterator);
            }
            return base.Equals(obj);
        }

        public override string ToString()
        {
            return _opterator;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public static bool operator ==(Opterator p1, Opterator p2)
        {
            return p1.Equals(p2);
        }

        public static bool operator !=(Opterator p1, Opterator p2)
        {
            return !p1.Equals(p2);
        }

        #endregion
    }

    /// <summary>
    /// 表示要进行 "+=,-= 之类的操作"
    /// </summary>
    public class OpteratorValue
    {
        public OpteratorValue() { }

        public OpteratorValue(Opterator opter,object value) 
        {
            Opterator = opter;
            Value = value;
        }

        /// <summary>
        /// 操作运算符
        /// </summary>
        public Opterator Opterator { get; set; }

        /// <summary>
        /// 值
        /// </summary>
        public object Value { get; set; }

        /// <summary>
        /// 生成语句 " [列名] = [列名] + 参数名"
        /// </summary>
        /// <param name="name">列名</param>
        /// <param name="param">参数名</param>
        public string ToOpteratorString(string name, string param)
        {
            return Opterator.ToOpteratorString(name, param);
        }

        /// <summary>
        /// 或取操作运算符
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Opterator.ToString();
        }
    }
}
